package br.com.q7solucoes.parsercinemaq7;

import br.com.q7solucoes.commons.utils.FileUtilsFromJar;
import br.com.q7solucoes.commons.utils.TextFile;
import br.com.q7solucoes.commons.wordpress.WPPostDAO;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

/**
 * Classe principal do projeto que tem o intuito de fazer o parser de sites de
 * cinema e insere em um site do Wordpress.
 *
 * @author Elenilson Vieira - elenilson[at]q7solucoes.com.br
 * @since 9 de setembro de 2011
 * @version 1.0
 * @see www.q7solucoes.com.br
 */
public class Main {

    public static final String PATH_INTO_PROJECT_OF_CONFIG_FILE = "/br/com/q7solucoes/parsercinemaq7/files/parsercinemaq7.config";
    public static final String LOG_FILE_PATH = "parsercinemaq7.log";
    public static final String TEMP_FOLDER_PATH = "temp";

    /**
     * Metodo inicial
     *
     * @param args argumentos da linha de comando
     */
    public static void main(String[] args) throws IOException, URISyntaxException, IllegalAccessException, Exception {
        try{
            createDefaultConfigurationFile();

            String email = ServerConfigurationFileWrapper.getInstance().getEmail();
            String emailPassword = ServerConfigurationFileWrapper.getInstance().getPasswordEmail();
            String hostMysqlDatabase = ServerConfigurationFileWrapper.getInstance().getMysqlDatabaseHost();
            String mysqlDatabase = ServerConfigurationFileWrapper.getInstance().getMysqlDatabase();
            String mysqlDatabaseCode = ServerConfigurationFileWrapper.getInstance().getMysqlDatabaseCode();
            String userMysqlDatabase = ServerConfigurationFileWrapper.getInstance().getMysqlDatabaseUser();
            String passwordMysqlDatabase = ServerConfigurationFileWrapper.getInstance().getMysqlDatabasePassword();
            String googleMovieURLs[] = ServerConfigurationFileWrapper.getInstance().getGoogleMovieURL();
            URLParser.URLType[] otherURLs = ServerConfigurationFileWrapper.getInstance().getOtherURLs();
            Date lastQuery = ServerConfigurationFileWrapper.getInstance().getLastQuery();
            int dayToQuery = ServerConfigurationFileWrapper.getInstance().getDayToQuery();
            int hourToQuery = ServerConfigurationFileWrapper.getInstance().getHourToQuery();
            boolean replicate = ServerConfigurationFileWrapper.getInstance().isReplicate();

            while(true){
                lastQuery = ServerConfigurationFileWrapper.getInstance().getLastQuery();
                Calendar lastDayToQuery = GregorianCalendar.getInstance();

                int preferredDayInCalendar = preferredDayToCalendarPreferredDay(dayToQuery);

                /*** Volta para a ultimo dia preferido para envio ***/
                while (lastDayToQuery.get(Calendar.DAY_OF_WEEK) != preferredDayInCalendar) {
                    lastDayToQuery.add(Calendar.DAY_OF_YEAR, -1);
                }
                
                lastDayToQuery.set(Calendar.HOUR_OF_DAY, hourToQuery);
                lastDayToQuery.set(Calendar.MINUTE, 0);
                lastDayToQuery.set(Calendar.SECOND, 0);
                lastDayToQuery.set(Calendar.MILLISECOND, 0);

                Calendar lastQueryCalendar = new GregorianCalendar();
                lastQueryCalendar.setTime(lastQuery);
                
                boolean canDo = lastDayToQuery.after(lastQueryCalendar);
                
                saveInfo(String.format("Comparacao de %s | e | %s | deu %b", lastDayToQuery.getTime().toString(), lastQueryCalendar.getTime().toString(), canDo));
                
                long timeToSleep = 300000;
                WPPostDAO wPPostDAO = null;

                try{
                    wPPostDAO = new WPPostDAO(mysqlDatabase, hostMysqlDatabase, userMysqlDatabase, passwordMysqlDatabase, mysqlDatabaseCode);
                }catch(Exception ex){
                    canDo = false;
                    saveLog(ex);
                }

                if(canDo){
                    /*** Faz o parse ***/
                    List<URLParserThread> threads = new ArrayList<URLParserThread>();

                    /*** Faz o parse de URLs google ***/
                    if(googleMovieURLs != null){
                        for (String googleMovieURL : googleMovieURLs) {
                            URLParserThread t = new URLParserThread(googleMovieURL, URLParser.URLType.GOOGLE_MOVIE, wPPostDAO, replicate);
                            threads.add(t);
                            t.start();
                        }
                    }

                    /*** faz o parse de url nao google ***/
                    if(otherURLs != null){
                        for (URLParser.URLType uRLType : otherURLs) {
                            URLParserThread t = new URLParserThread(uRLType, wPPostDAO, replicate);
                            threads.add(t);
                            t.start();
                        }
                    }

                    /*** Espera as threads acabarem e verifica se deu algum erro ***/
                    for (URLParserThread uRLParserThread : threads) {
                        uRLParserThread.join();

                        if(uRLParserThread.getError() != null)
                            saveLog(uRLParserThread.getError());
                    }

                    saveResult(true);
                    ServerConfigurationFileWrapper.getInstance().setLastQuery(GregorianCalendar.getInstance().getTime());
                }else{
                    Calendar now = GregorianCalendar.getInstance();
                    Calendar next = (Calendar) now.clone();

                    /*** Volta para a ultimo dia preferido para envio ***/
                    while (next.get(Calendar.DAY_OF_WEEK) != preferredDayInCalendar) {
                        next.add(Calendar.DAY_OF_YEAR, 1);
                    }

                    next.set(Calendar.HOUR_OF_DAY, hourToQuery);
                    next.set(Calendar.MINUTE, 0);
                    next.set(Calendar.SECOND, 0);

                    timeToSleep = next.getTimeInMillis() - now.getTimeInMillis();

                    if(timeToSleep <= 0)
                        timeToSleep = 300000;
                }

                try{
                    Thread.sleep(timeToSleep);
                }catch(Exception ex){}
            }
        }catch(Exception ex){
            saveLog(ex);
            throw ex;
        }
    }

    private static void createDefaultConfigurationFile() throws IOException, URISyntaxException, IllegalAccessException {
        File locationToWrite = new File(ServerConfigurationFileWrapper.CONFIGURATION_FILE_PATH);

        if (locationToWrite.exists()) {
            return;
        }

        String content = FileUtilsFromJar.readStringFromAFileJar(PATH_INTO_PROJECT_OF_CONFIG_FILE);
        TextFile textFile = new TextFile(locationToWrite);
        textFile.setContent(content);
    }

    private static int preferredDayToCalendarPreferredDay(int preferredDay) {

        switch (preferredDay) {
            case 0:
                return Calendar.SUNDAY;
            case 1:
                return Calendar.MONDAY;
            case 2:
                return Calendar.TUESDAY;
            case 3:
                return Calendar.WEDNESDAY;
            case 4:
                return Calendar.THURSDAY;
            case 5:
                return Calendar.FRIDAY;
            case 6:
                return Calendar.SATURDAY;
            default:
                return Calendar.THURSDAY;
        }
    }
    
    private static void saveResult(boolean result) {
        try{
            Date now = GregorianCalendar.getInstance().getTime();
            TextFile textFile = new TextFile(LOG_FILE_PATH);
            StringBuilder log = new StringBuilder();

            if(result){
                log
                        .append("############################    SUCESSO    #############################\n");
            }
            else{
                log
                        .append("############################ ERRO NO TWEET #############################\n");
            }

            log
                    .append(now.toString()).append("\n")
                    .append("########################################################################\n\n");

            textFile.addContent(log.toString());
        }catch(Exception ex){}
    }

    private static void saveLog(Exception ex) {
        try{
            Date now = GregorianCalendar.getInstance().getTime();
            TextFile textFile = new TextFile(LOG_FILE_PATH);
            StringBuilder log = new StringBuilder();

            log
                    .append("############################## ERRO FATAL ##############################\n")
                    .append(now.toString()).append("\n")
                    .append(ex.getMessage()).append("\n")
                    .append("########################################################################\n\n");

            textFile.addContent(log.toString());
        }catch(Exception exX){}
    }

    private static void saveInfo(String info) {
        try{
            Date now = GregorianCalendar.getInstance().getTime();
            TextFile textFile = new TextFile(LOG_FILE_PATH);
            StringBuilder log = new StringBuilder();

            log
                    .append("################################# INFO ################################\n")
                    .append(now.toString()).append("\n")
                    .append(info).append("\n")
                    .append("########################################################################\n\n");

            textFile.addContent(log.toString());
        }catch(Exception exX){}
    }
    
    

}
